package com.hk.commons.poi.excel.read.builder;


import com.hk.commons.poi.excel.metadata.ReadResult;
import com.hk.commons.poi.excel.metadata.ReadWorkbook;
import com.hk.commons.poi.excel.read.ExcelReader;
import com.hk.commons.poi.excel.read.ReadMode;
import com.hk.commons.poi.excel.util.ReadExcelUtils;
import com.hk.commons.util.AssertUtils;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.Collections;
import java.util.Map;


/**
 * Excel read 构建器，构建读取的一些参数设置
 *
 * @author Kevin
 */
public class ExcelReaderBuilder {

    private final ReadWorkbook readWorkbook;

    public ExcelReaderBuilder(Class<?> beanClass) {
        this.readWorkbook = new ReadWorkbook();
        this.readWorkbook.setBeanClass(beanClass);
    }

    public ExcelReaderBuilder file(File file) {
        this.readWorkbook.setFile(file);
        return this;
    }

    public ExcelReaderBuilder file(InputStream inputStream) {
        if (!inputStream.markSupported()) {
            inputStream = new BufferedInputStream(inputStream);
        }
        this.readWorkbook.setInputStream(inputStream);
        return this;
    }

    public ExcelReaderBuilder titleRow(int titleRow) {
        this.readWorkbook.setTitleRow(titleRow);
        return this;
    }

    public ExcelReaderBuilder sheetStartRow(int sheetStartRow) {
        this.readWorkbook.setSheetStartRow(sheetStartRow);
        return this;
    }

    public ExcelReaderBuilder sheetMaxRow(int sheetMaxRow) {
        this.readWorkbook.setSheetMaxRow(sheetMaxRow);
        return this;
    }

    public ExcelReaderBuilder parseAllSheet(boolean parseAllSheet) {
        this.readWorkbook.setParseAllSheet(parseAllSheet);
        return this;
    }

    public ExcelReaderBuilder startSheetIndex(int startSheetIndex) {
        this.readWorkbook.setStartSheetIndex(startSheetIndex);
        return this;
    }

    public ExcelReaderBuilder maxSheetIndex(int maxSheetIndex) {
        this.readWorkbook.setMaxSheetIndex(maxSheetIndex);
        return this;
    }

    public ExcelReaderBuilder outFormulaValue(boolean outFormulaValue) {
        this.readWorkbook.setOutFormulaValue(outFormulaValue);
        return this;
    }

    public ExcelReaderBuilder ignoreLineBreak(boolean ignoreLineBreak) {
        this.readWorkbook.setIgnoreLineBreak(ignoreLineBreak);
        return this;
    }

    public ExcelReaderBuilder autoTrim(boolean autoTrim) {
        this.readWorkbook.setAutoTrim(autoTrim);
        return this;
    }

    public ExcelReaderBuilder readMode(ReadMode readMode) {
        this.readWorkbook.setReadMode(readMode);
        return this;
    }

    public ExcelReaderBuilder useAnnotationColumnField() {
        this.readWorkbook.setColumnField(ReadExcelUtils.getReadExcelAnnotationMapping(this.readWorkbook.getBeanClass()));
        return this;
    }

    public ExcelReaderBuilder customColumnField(Map<Integer, String> columnFieldMap) {
        this.readWorkbook.setColumnField(Collections.unmodifiableMap(columnFieldMap));
        return this;
    }

    public <T> ExcelReader<T> build() {
        return new ExcelReader<>(readWorkbook);
    }

    @SuppressWarnings("unchecked")
    public <T> ReadResult<T> read() {
        AssertUtils.notNull(readWorkbook.getBeanClass(), "ReadParam beanClazz must not be null");
        AssertUtils.isTrue(readWorkbook.getTitleRow() < readWorkbook.getSheetStartRow(), "标题行必须小于数据开始行");
        if (!readWorkbook.isParseAllSheet()) {
            AssertUtils.isTrue(readWorkbook.getStartSheetIndex() <= readWorkbook.getMaxSheetIndex(),
                    "开始解析的工作表必须小于等于结束解析的工作表");
        }
        return (ReadResult<T>) build().read();
    }

}
